﻿namespace HostTracker.Azure.ProjectSettings

open System
open System.IO
open System.Xml
open System.Text
open System.ServiceModel
open System.ServiceModel.Web
open System.Xml.Serialization

//[<DataContract(Name = "Setting", Namespace = "http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration")>]
[<SerializableAttribute>]
type Setting() = 
    let mutable name = ""
    let mutable value = ""
    static let devDiagnostics = Setting(Name = "Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString", Value = "UseDevelopmentStorage=true")
    [<XmlAttributeAttribute(AttributeName="name")>]
    //[<DataMember(Name = "name", Order = 1)>]
    member x.Name with get () = name and set v = name <- v
    [<XmlAttributeAttribute(AttributeName="value")>]
    //[<DataMember(Name = "value", Order = 2)>]
    member x.Value with get () = value and set v = value <- v
    [<XmlIgnoreAttribute>]
    static member UseDevelopmentStorage = devDiagnostics

//[<CollectionDataContract(Name = "ConfigurationSettings", Namespace = "http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration")>]
[<SerializableAttribute>]
type ConfigurationSettings() = 
    inherit System.Collections.Generic.List<Setting>()

//[<DataContract(Name = "Certificate", Namespace = "http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration")>]
[<SerializableAttribute>]
type Certificate() = 
    let mutable name = ""
    let mutable thumbprint = ""
    let mutable thumbprintAlgorithm = ""
    [<XmlAttributeAttribute(AttributeName="name")>]
    //[<DataMember(Name = "name", Order = 1)>]
    member x.Name with get () = name and set v = name <- v
    [<XmlAttributeAttribute(AttributeName="thumbprint")>]
    //[<DataMember(Name = "thumbprint", Order = 2)>]
    member x.Thumbprint with get () = thumbprint and set v = thumbprint <- v
    [<XmlAttributeAttribute(AttributeName="thumbprintAlgorithm")>]
    //[<DataMember(Name = "thumbprintAlgorithm", Order = 3)>]
    member x.ThumbprintAlgorithm with get () = thumbprintAlgorithm and set v = thumbprintAlgorithm <- v

//[<CollectionDataContract(Name = "Certificates", Namespace = "http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration")>]
[<SerializableAttribute>]
type Certificates() = 
    inherit System.Collections.Generic.List<Certificate>()

//[<DataContract(Name = "Instances", Namespace = "http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration")>]
[<SerializableAttribute>]
type InstanceConfig() = 
    let mutable count = 1
    [<XmlAttributeAttribute(AttributeName="count")>]
    //[<DataMember(Name = "count", Order = 1)>]
    member x.Count with get () = count and set v = count <- v

//[<DataContract(Name = "Role", Namespace = "http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration")>]
[<SerializableAttribute>]
type Role() =
    let mutable name = ""
    let mutable instnceConfig = InstanceConfig()
    let mutable configSettings = ConfigurationSettings()
    let mutable certs = Certificates()
    [<XmlAttributeAttribute(AttributeName="name")>]
    //[<DataMember(Name = "name", Order = 1)>]
    member x.Name with get () = name and set v = name <- v
    //[<DataMember(Name = "Instances", Order = 2)>]
    [<XmlElementAttribute("Instances", typeof<InstanceConfig>)>]
    member x.InstanceConfig with get () = instnceConfig and set v = instnceConfig <- v
    //[<DataMember(Name = "ConfigurationSettings", Order = 3)>]
    [<XmlElementAttribute("ConfigurationSettings", typeof<ConfigurationSettings>)>]
    member x.ConfigurationSettings with get () = configSettings and set v = configSettings <- v
    //[<DataMember(Name = "Certificates", Order = 4)>]
    [<XmlElementAttribute("Certificates", typeof<Certificates>)>]
    member x.Certificates with get () = certs and set v = certs <- v
    
[<XmlRootAttribute("ServiceConfiguration", Namespace = "http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration")>]
type ServiceConfiguration() =
    //inherit System.Collections.Generic.List<Role>()
    let mutable name = ""
    let mutable osFamily = "1"
    let mutable osVersion = "*"
    let mutable roles = System.Collections.Generic.List<Role>()
    [<XmlAttributeAttribute("serviceName")>]
    member x.ServiceName with get () = name and set v = name <- v
    [<XmlAttributeAttribute("osFamily")>]
    member x.OsFamily with get () = osFamily and set v = osFamily <- v
    [<XmlAttributeAttribute("osVersion")>]
    member x.OsVersion with get () = osVersion and set v = osVersion <- v
    [<XmlElementAttribute("Role", typeof<Role>)>]
    member x.Roles with get () = roles and set v = roles <- v
    static member LoadFromFile(path) =
        use xmlStream = File.OpenRead(path)
        use reader = XmlReader.Create(xmlStream)
        let serializer = XmlSerializer(typeof<ServiceConfiguration>)
        serializer.Deserialize(reader) :?> ServiceConfiguration
    static member LoadFromString(xml: string) =
        use xmlStream = new MemoryStream(Encoding.UTF8.GetBytes(xml), false)
        use reader = XmlReader.Create(xmlStream)
        let serializer = XmlSerializer(typeof<ServiceConfiguration>)
        serializer.Deserialize(reader) :?> ServiceConfiguration
    member x.SaveToFile(path) =
        let ns = new XmlSerializerNamespaces();
        ns.Add("", "http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration");
        use xmlStream = File.Open(path, FileMode.Create)
        use writer = XmlWriter.Create(xmlStream)
        let serializer = XmlSerializer(typeof<ServiceConfiguration>)
        serializer.Serialize(writer, x, ns)
    override x.ToString() = 
        let ns = new XmlSerializerNamespaces();
        ns.Add("", "http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration");
        let builder = StringBuilder()
        use writer = XmlWriter.Create(builder)
        let serializer = XmlSerializer(typeof<ServiceConfiguration>)
        serializer.Serialize(writer, x, ns)    
        writer.Flush()
        builder.ToString()        